﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Klinkby.PodCaster
{
    using Model;
    using Properties;

    delegate void CommandCallback(IPersistingModel model, string[] args);

    class Program
    {
        readonly static IEnumerable<KeyValuePair<Commands, CommandCallback>> _commands = new[] {
            new KeyValuePair<Commands, CommandCallback>(Commands.ADD, Add),
            new KeyValuePair<Commands, CommandCallback>(Commands.LIST, List),
            new KeyValuePair<Commands, CommandCallback>(Commands.REFRESH, Refresh),
            new KeyValuePair<Commands, CommandCallback>(Commands.REMOVE, Remove),
        };

        static void Add(IPersistingModel model, string[] args)
        {
            Uri url = new Uri(args[1], UriKind.Absolute);
            var feed = Feed.FromUrl(url);
            model.Feeds.Add(feed);
            model.Download();
        }

        static void List(IPersistingModel model, string[] args)
        {
            foreach (var feed in model.Feeds)
            {
                Console.WriteLine("{0}\t{1}", feed.Title, feed.Url);
                foreach (var post in feed.Posts)
                {
                    Console.WriteLine("\t\t{0}\t{1}\t{2}", post.Title, post.DownloadStatus, post.FilePath);
                    foreach (var postUrl in post.Urls)
                        Console.WriteLine("\t\t\t\t\t\t\t{0}", postUrl);
                }
            }
        }

        static void Remove(IPersistingModel model, string[] args)
        {
            Uri url = new Uri(args[1], UriKind.Absolute);
            model.Feeds.Remove(model.Feeds.First(feed => feed.Url == url));
        }

        static void Refresh(IPersistingModel model, string[] args)
        {
            model.RefreshFeeds();
            model.Download();
        }

        static void Usage()
        {
            Console.Error.WriteLine(Resources.UsageFormat, Process.GetCurrentProcess().ProcessName);
        }

        [STAThread]
        static int Main(string[] args)
        {
            try
            {
                Commands command = (Commands)Enum.Parse(typeof(Commands), args[0].ToUpperInvariant());
                IPersistingModel model = PersistingModel.Load(Settings.Default.FeedsXml);
                _commands.First(item => item.Key == command).Value(model, args);
                model.Save();
                return 0;
            }
            catch (ArgumentException)
            {
                Usage();
                return 1;
            }
            catch (IndexOutOfRangeException)
            {
                Usage();
                return 1;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return  13804;
            }
        }
    }
}
